package com.gourd.file.controller;

import com.gourd.common.utils.CommonUtil;
import com.gourd.file.file.vo.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;


/**
 * @author gourd
 */
@RestController
@RequestMapping("/file")
@Api(tags = "file", description = "文件控制器")
@RefreshScope
public class FileController {
   
   @Value("${spring.multipart.uploadFolder}")
   private String getUploadFolder;


    @Value("${spring.multipart.windowsUploadFolder}")
    private String windowsUploadFolder;


   /**
    * 上传文件
    * @param request
    * @param response
    * @param guid
    * @param chunk
    * @param file
    * @param chunks
    */
   @PostMapping("/upload")
   @ApiOperation(value="上传文件")
   public void bigFile(HttpServletRequest request, HttpServletResponse response,String guid,Integer chunk, MultipartFile file,Integer chunks){
      try {  
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
            if (isMultipart) {  
                // 临时目录用来存放所有分片文件  
                String tempFileDir = getUploadFolder() + guid;
                File parentFileDir = new File(tempFileDir);  
                if (!parentFileDir.exists()) {  
                    parentFileDir.mkdirs();  
                }  
                // 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台  
                File tempPartFile = new File(parentFileDir, guid + "_" + chunk + ".part");
                FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);  
            }  
        } catch (Exception e) {  
           e.printStackTrace();
        }  
   }
   
   /**
    * 合并文件
    * @param guid
    * @param fileName
    * @throws Exception
    */
   @PostMapping("/merge")
   @ApiOperation(value="合并文件")
   @ResponseBody
   public JsonResult mergeFile(String guid,String fileName){
       // 得到 destTempFile 就是最终的文件  
      try {
         File parentFileDir = new File(getUploadFolder() + guid);
         if(parentFileDir.isDirectory()){
            File destTempFile = new File(getUploadFolder() + "/merge", fileName);
            if(!destTempFile.exists()){
               //先得到文件的上级目录，并创建上级目录，在创建文件,
               destTempFile.getParentFile().mkdir();
               try {
                  //创建文件
                  destTempFile.createNewFile(); //上级目录没有创建，这里会报错
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
            System.out.println(parentFileDir.listFiles().length);
              for (int i = 0; i < parentFileDir.listFiles().length; i++) {  
                  File partFile = new File(parentFileDir, guid + "_" + i + ".part");
                  FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
                  //遍历"所有分片文件"到"最终文件"中  
                  FileUtils.copyFile(partFile, destTempfos);  
                  destTempfos.close();  
              }  
              // 删除临时目录中的分片文件  
              FileUtils.deleteDirectory(parentFileDir);
              return JsonResult.success();
         }
      } catch (Exception e) {
         e.printStackTrace();
         return JsonResult.fail();
      }
      return null;
   }

    /**
     * 文件下载相关代码
     * @param request
     * @param response
     * @param id
     * @return
     * @throws Exception
     */
    @GetMapping("/down/{id}")
    @ApiOperation(value="下载文件")
    public String downloadFile(HttpServletRequest request, HttpServletResponse response, @PathVariable String id) throws Exception {

        // 根据id查询相关的文件信息、这里测试写死
        // 设置文件名，根据业务需要替换成要下载的文件名
        String fileName = "用户手册.pdf";
        if (fileName != null) {
            //设置文件路径
            String realPath = getUploadFolder();
            File file = new File(realPath , fileName);
            if (file.exists()) {
                // 设置强制下载不打开
                response.setContentType("application/force-download");
                // 设置文件名
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                // //也可以明确的设置一下UTF-8，测试中不设置也可以。
                response.setContentType("multipart/form-data;charset=UTF-8");
                response.setHeader("Content-Disposition", "attachment;fileName="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1"));
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    System.out.println("下载成功");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取文件临时路径
     *
     * @return
     */
    private String getUploadFolder(){
       String filePath;
       if(CommonUtil.isLinux()){
           filePath = getUploadFolder();
       }else {
           filePath = windowsUploadFolder;
       }
       return filePath;
    }
}